using MapsterMapper;
using AiQiuQuan.Sport.Model.Models;
using AiQiuQuan.Sport.Core;
using AiQiuQuan.Sport.WebApi.Entities;
using AiQiuQuan.Sport.WebApi.Repositories;
using Microsoft.EntityFrameworkCore;

namespace AiQiuQuan.Sport.WebApi.Services.Impl
{
    /// <summary>
    /// 广告管理
    /// </summary>
    public class AdvertisementService : IAdvertisementService
    {
        private readonly IMapper _mapper;
        private readonly IAdvertisementRepository _advertisementRepository;
        private readonly IProvinceRepository _provinceRepository;
        private readonly ICityRepository _cityRepository;

        /// <summary>
        /// ctor
        /// </summary>
        public AdvertisementService(
            IMapper mapper,
            IAdvertisementRepository advertisementRepository,
            IProvinceRepository provinceRepository,
            ICityRepository cityRepository)
        {
            _mapper = mapper;
            _advertisementRepository = advertisementRepository;
            _provinceRepository = provinceRepository;
            _cityRepository = cityRepository;
        }

        /// <summary>
        /// 查询一条记录
        /// </summary>
        public async Task<AdvertisementDto> GetAsync(Guid id)
        {
            var advertisement = await _advertisementRepository.FirstOrDefaultAsync(m => m.ID == id);
            return _mapper.Map<Advertisement, AdvertisementDto>(advertisement);
        }

        /// <summary>
        /// 查询
        /// </summary>
        public async Task<AdvertisementDto> QueryAsync(AdvertisementQueryRequestDto request)
        {
            var queryable = _advertisementRepository.AsNoTracking().Where(m => m.BusinessType == request.BusinessType);
            if (request.ProvinceId.HasValue && request.CityId.HasValue)
            {
                queryable = queryable.Where(m => m.ProvinceId == request.ProvinceId.Value && m.CityId == request.CityId.Value);
            }
            else if (request.ProvinceId.HasValue)
            {
                queryable = queryable.Where(m => m.ProvinceId == request.ProvinceId.Value);
            }

            var advert = await queryable.FirstOrDefaultAsync();
            var result = _mapper.Map<AdvertisementDto>(advert);
            return result;
        }

        /// <summary>
        /// 分页列表
        /// </summary>
        public async Task<PageResult<AdvertisementDto>> PageListAsync(AdvertisementPageRequestDto request)
        {
            var queryable = CreateAdvertPageQueryable(request);
            var pageResult = await queryable.OrderByDescending(m => m.CreateTime)
                .PageListAsync<Advertisement, AdvertisementDto>(request, _mapper);
            return pageResult;
        }

        /// <summary>
        /// 新增
        /// </summary>
        public async Task<UnaryResult> AddAsync(AdvertisementAddDto model)
        {
            var advertisement = _mapper.Map<Advertisement>(model);
            var unaryResult = await ValidAddOrUpdateAsync(advertisement);
            if (unaryResult.Code != 0)
            {
                return unaryResult;
            }

            await SetRegionInfoAsync(advertisement);
            await _advertisementRepository.AddAsync(advertisement);
            return UnaryResult.Succeed();
        }

        /// <summary>
        /// 修改
        /// </summary>
        public async Task<UnaryResult> UpdateAsync(AdvertisementUpdateDto model)
        {
            var advertisement = await _advertisementRepository.FirstOrDefaultAsync(m => m.ID == model.ID);
            if (advertisement == null)
            {
                return UnaryResult.Faild(10, "广告不存在");
            }

            _mapper.Map(model, advertisement);
            var unaryResult = await ValidAddOrUpdateAsync(advertisement);
            if (unaryResult.Code != 0)
            {
                return unaryResult;
            }

            await SetRegionInfoAsync(advertisement);
            await _advertisementRepository.UpdateAsync(advertisement);
            return UnaryResult.Succeed();
        }

        /// <summary>
        /// 删除
        /// </summary>
        public async Task<UnaryResult> DeleteAsync(Guid id)
        {
            await _advertisementRepository.DeleteAsync(p => p.ID == id);
            return UnaryResult.Succeed();
        }

        #region private methods
        /// <summary>
        /// 设置广告省市名称
        /// </summary>
        private async Task SetRegionInfoAsync(Advertisement advert)
        {
            if (advert != null)
            {
                advert.Name ??= string.Empty;
                if (advert.ProvinceId.HasValue)
                {
                    var province = await _provinceRepository.AsNoTracking().FirstOrDefaultAsync(m => m.ID == advert.ProvinceId.Value);
                    advert.ProvinceName = province?.P_Name;
                }

                if (advert.CityId.HasValue)
                {
                    var city = await _cityRepository.AsNoTracking().FirstOrDefaultAsync(m => m.ID == advert.CityId.Value);
                    advert.ProvinceName = city?.C_Name;
                }
            }
        }

        /// <summary>
        /// 广告分页queryable
        /// </summary>
        private IQueryable<Advertisement> CreateAdvertPageQueryable(AdvertisementPageRequestDto request)
        {
            var queryable = _advertisementRepository.AsNoTracking();
            if (request.BusinessType.HasValue)
            {
                queryable = queryable.Where(m => m.BusinessType == request.BusinessType);
            }

            if (request.Type.HasValue)
            {
                queryable = queryable.Where(m => m.Type == request.Type);
            }

            if (request.CityId.HasValue && request.ProvinceId.HasValue)
            {
                queryable = queryable.Where(m => m.ProvinceId == request.ProvinceId.Value && m.CityId == request.CityId.Value);
            }
            else if (request.ProvinceId.HasValue)
            {
                queryable = queryable.Where(m => m.ProvinceId == request.ProvinceId.Value && m.CityId == request.CityId.Value);
            }

            if (!string.IsNullOrWhiteSpace(request.Name))
            {
                queryable = queryable.Where(m => m.Name.Contains(request.Name));
            }

            return queryable;
        }

        /// <summary>
        /// 新增/编辑广告验证
        /// </summary>
        private async Task<UnaryResult> ValidAddOrUpdateAsync(Advertisement advert)
        {
            var error = string.Empty;
            var queryable = _advertisementRepository.AsNoTracking().Where(m => m.BusinessType == advert.BusinessType);
            if (advert.ID != Guid.Empty)
            {
                queryable = queryable.Where(m => m.ID != advert.ID);
            }

            if (advert.ProvinceId.HasValue && advert.CityId.HasValue)
            {
                queryable = queryable.Where(m => m.ProvinceId == advert.ProvinceId.Value && m.CityId == advert.CityId.Value);
                error = "市内广告重复";
            }
            else if (advert.ProvinceId.HasValue)
            {
                queryable = queryable.Where(m => m.ProvinceId == advert.ProvinceId.Value);
                error = "省内广告重复";
            }
            else
            {
                error = "国内广告重复";
            }

            if (await queryable.AnyAsync())
            {
                return UnaryResult.Faild(10, error);
            }

            return UnaryResult.Succeed();
        }
        #endregion
    }
}
